import React, { useState } from 'react';
import { Input, Form, Icon, Tooltip, Radio, Button } from 'antd';
import debounce from 'lodash/debounce';
import isEqual from 'lodash/isEqual';
import { useDynamicList } from 'ahooks';
import get from 'lodash/get';
import { pick } from 'lodash';
import styles from '../styles.less';

import Mapper from './Mapper';
import CustomHandlerSelector from '@/components/CustomHandlerSelector';
import request from '@/utils/request';

// 对象数组转成对象 [{field,mapping}] => {[field]: mapping}
function serialize(list) {
  const result = {};

  list
    .filter(k => k.field)
    .forEach(k => {
      result[k.field] = k.mapping;
    });

  return result;
}

function getDefaultVariables(value) {
  const newList = Object.keys(get(value, 'variables') || []).map(k => ({
    field: k,
    mapping: get(value, `variables.${k}`),
  }));
  return newList.length > 0 ? newList : [{}];
}

function ForMultipleValue({
  treeData,
  value = {},
  onChange = () => {},
  custom = true,
  placeholder = '表达式如：#a + #b，a和b均为变量，需要手动添加',
}) {
  const { list, remove, getKey, insert } = useDynamicList(getDefaultVariables(value));
  const [helpInfo, setHelpInfo] = useState();
  const [validateStatus, setValidateStatus] = useState();
  const [validateLoading, setValidateLoading] = useState(false);

  const actionType = value.actionType || 'expression';

  const _notify = payload => {
    let newValue = { ...value, ...payload };
    const _actionType = payload.actionType || actionType;

    if (_actionType === 'expression') {
      newValue = {
        ...newValue,
        className: undefined,
        beanName: undefined,
        title: undefined,
        params: undefined,
        actionType: _actionType,
      };
    } else if (_actionType === 'custom') {
      newValue = { ...newValue, expression: undefined, actionType: _actionType };
    }

    if (!isEqual(value, newValue)) {
      onChange(newValue);
    }
  };

  const notify = debounce(_notify, 1000, { leading: false, trailing: true });

  const validateExpression = () => {
    setValidateLoading(true);
    request
      .post('/validation/validateExpression', {
        data: {
          expression: value.expression,
        },
      })
      .then(({ success, error }) => {
        if (success) {
          setHelpInfo(
            <span className="text-success">
              表达式验证通过
              <Icon style={{ marginLeft: 4 }} type="check-circle" theme="filled" />
            </span>
          );
          setValidateStatus('success');
        } else {
          setHelpInfo(
            <>
              {error}
              <Icon style={{ marginLeft: 4 }} type="close-circle" theme="filled" />
            </>
          );
          setValidateStatus('error');
        }
      })
      .finally(() => {
        setValidateLoading(false);
      });
  };

  return (
    <>
      <div className="margin-bottom">
        {custom && (
          <Radio.Group
            value={actionType}
            onChange={e => {
              _notify({ actionType: e.target.value });
            }}
            buttonStyle="solid"
            className="margin-z"
            style={{ display: 'block' }}
          >
            <Radio.Button key="expression" value="expression">
              表达式运算
              <Tooltip title="引用的变量名需自定义">
                <Icon
                  type="info-circle"
                  className="margin-left-sm"
                  style={{ verticalAlign: 'middle', marginTop: -3 }}
                />
              </Tooltip>
            </Radio.Button>
            <Radio.Button key="custom" value="custom">
              自定义转换器
            </Radio.Button>
          </Radio.Group>
        )}

        {actionType === 'expression' && (
          <Form.Item validateStatus={validateStatus} help={helpInfo}>
            <Input
              className={styles.expression}
              defaultValue={value.expression}
              placeholder={placeholder}
              onChange={e => {
                _notify({ expression: e.target.value });
              }}
              suffix={
                <Button
                  style={{ padding: 0 }}
                  type="link"
                  loading={validateLoading}
                  onClick={validateExpression}
                >
                  校验合法性
                </Button>
              }
            />
          </Form.Item>
        )}

        {actionType === 'custom' && (
          <CustomHandlerSelector
            url="/transform/listCustomMultiValuesTransformers"
            value={pick(value, ['className', 'beanName', 'title', 'params'])}
            onChange={_notify}
          />
        )}
      </div>
      {list.map((k, i) => (
        <div key={getKey(i)} className="margin-bottom-lg">
          <div className="margin-bottom clearfix">
            <span className="pull-right">
              {i !== 0 && (
                <Tooltip title="删除变量">
                  <Icon
                    type="delete"
                    className="margin-left"
                    onClick={() => {
                      remove(i);
                      // 传递当前值
                      const l = [...list];
                      l.splice(i, 1);
                      notify({ variables: serialize(l) });
                    }}
                  />
                </Tooltip>
              )}
              <Tooltip title="添加变量">
                <Icon
                  type="plus-circle"
                  className="margin-left-lg"
                  onClick={() => {
                    insert(i + 1, {});
                  }}
                />
              </Tooltip>
            </span>
            <span className="bold">#{i + 1} </span>
          </div>
          <Form.Item label="变量名" required name={['keyField', getKey(i)]}>
            <Input
              placeholder="请输入"
              defaultValue={k.field}
              onChange={e => {
                // 传递当前值
                const l = [...list];
                l[i].field = e.target.value;

                notify({ variables: serialize(l) });
              }}
            />
          </Form.Item>
          <Form.Item label="变量取值" required>
            <Mapper
              treeData={treeData}
              value={k.mapping}
              onChange={data => {
                // 传递当前值
                const l = [...list];
                l[i].mapping = data;

                notify({ variables: serialize(l) });
              }}
            />
          </Form.Item>
        </div>
      ))}
    </>
  );
}

export default ForMultipleValue;
